package cn.blnp.net.flowable.boot.custom.activity;

import cn.blnp.net.flowable.boot.config.flowable.FlowableEngineConfiguration;
import cn.blnp.net.flowable.boot.config.flowable.behavior.CustomActivityBehaviorFactory;
import cn.blnp.net.flowable.boot.config.flowable.behavior.CustomUserTaskActivityBehavior;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.filter.SimplePropertyPreFilter;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.IdentityService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.identitylink.api.IdentityLink;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.List;

/**
 * <h3></h3>
 *
 * @author <a href="mailto:blnp.yibin@qq.com">lyb</a>
 * @version 1.0
 * @since 2025/6/6 11:28
 */
@Slf4j
@SpringBootTest
public class CusFlowActivityTest {

    @Resource
    private RepositoryService repositoryService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private IdentityService identityService;
    @Resource
    private TaskService taskService;

    /**
     *  <h1>流程活动与Behavior对应关系</h1>
     *  <ol>
     *      <li><b>空开始事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.NoneStartEventActivityBehavior}</li>
     *      <li><b>空结束事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.NoneEndEventActivityBehavior}</li>
     *      <li><b>取消结束事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.CancelEndEventActivityBehavior}</li>
     *      <li><b>错误结束事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.ErrorEndEventActivityBehavior}</li>
     *      <li><b>终止结束事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.TerminateEndEventActivityBehavior}</li>
     *      <li><b>升级结束事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.EscalationEndEventActivityBehavior}</li>
     *      <li><b>用户任务：</b>{@link org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior}</li>
     *      <li><b>排他网关：</b>{@link org.flowable.engine.impl.bpmn.behavior.ExclusiveGatewayActivityBehavior}</li>
     *      <li><b>包容网关：</b>{@link org.flowable.engine.impl.bpmn.behavior.InclusiveGatewayActivityBehavior}</li>
     *      <li><b>并行网关：</b>{@link org.flowable.engine.impl.bpmn.behavior.ParallelGatewayActivityBehavior}</li>
     *      <li><b>事件网关：</b>{@link org.flowable.engine.impl.bpmn.behavior.EventBasedGatewayActivityBehavior}</li>
     *      <li><b>接收任务：</b>{@link org.flowable.engine.impl.bpmn.behavior.ReceiveTaskActivityBehavior}</li>
     *      <li><b>脚本任务：</b>{@link org.flowable.engine.impl.bpmn.behavior.ScriptTaskActivityBehavior}</li>
     *      <li><b>邮件任务：</b>{@link org.flowable.engine.impl.bpmn.behavior.MailActivityBehavior}</li>
     *      <li><b>手动任务：</b>{@link org.flowable.engine.impl.bpmn.behavior.ManualTaskActivityBehavior}</li>
     *      <li><b>Shell任务：</b>{@link org.flowable.engine.impl.bpmn.behavior.ShellActivityBehavior}</li>
     *      <li><b>Web Service任务：</b>{@link org.flowable.engine.impl.bpmn.behavior.WebServiceActivityBehavior}</li>
     *      <li><b>接收事件任务：</b>{@link org.flowable.engine.impl.bpmn.behavior.ReceiveEventTaskActivityBehavior}</li>
     *      <li><b>发送事件任务：</b>{@link org.flowable.engine.impl.bpmn.behavior.SendEventTaskActivityBehavior}</li>
     *      <li><b>业务规则任务：</b>{@link org.flowable.engine.impl.bpmn.behavior.BusinessRuleTaskActivityBehavior}</li>
     *      <li><b>外部工作者任务：</b>{@link org.flowable.engine.impl.bpmn.behavior.ExternalWorkerTaskActivityBehavior}</li>
     *      <li><b>Case任务：</b>{@link org.flowable.engine.impl.bpmn.behavior.CaseTaskActivityBehavior}</li>
     *      <li><b>DMN任务：</b>{@link org.flowable.engine.impl.bpmn.behavior.DmnActivityBehavior}</li>
     *      <li><b>取消边界事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.BoundaryCancelEventActivityBehavior}</li>
     *      <li><b>补偿边界事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.BoundaryCompensateEventActivityBehavior}</li>
     *      <li><b>消息边界事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.BoundaryMessageEventActivityBehavior}</li>
     *      <li><b>信号边界事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.BoundarySignalEventActivityBehavior}</li>
     *      <li><b>定时器边界事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.BoundaryTimerEventActivityBehavior}</li>
     *      <li><b>条件边界事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.BoundaryConditionalEventActivityBehavior}</li>
     *      <li><b>升级边界事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.BoundaryEscalationEventActivityBehavior}</li>
     *      <li><b>注册事件边界事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.BoundaryEventRegistryEventActivityBehavior}</li>
     *      <li><b>变量监听边界事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.BoundaryVariableListenerEventActivityBehavior}</li>
     *      <li><b>服务任务（delegateExpression）：</b>{@link org.flowable.engine.impl.bpmn.behavior.ServiceTaskDelegateExpressionActivityBehavior}</li>
     *      <li><b>服务任务（expression）：</b>{@link org.flowable.engine.impl.bpmn.behavior.ServiceTaskExpressionActivityBehavior}</li>
     *      <li><b>服务任务（串行-class）：</b>{@link org.flowable.engine.impl.bpmn.behavior.ServiceTaskJavaDelegateActivityBehavior}</li>
     *      <li><b>服务任务（并行-class）：</b>{@link org.flowable.engine.impl.bpmn.behavior.ServiceTaskFutureJavaDelegateActivityBehavior}</li>
     *      <li><b>调用活动：</b>{@link org.flowable.engine.impl.bpmn.behavior.CallActivityBehavior}</li>
     *      <li><b>内嵌子流程：</b>{@link org.flowable.engine.impl.bpmn.behavior.SubProcessActivityBehavior}</li>
     *      <li><b>事务子流程：</b>{@link org.flowable.engine.impl.bpmn.behavior.TransactionActivityBehavior}</li>
     *      <li><b>事务子流程（通过错误开始事件发起）：</b>{@link org.flowable.engine.impl.bpmn.behavior.EventSubProcessErrorStartEventActivityBehavior}</li>
     *      <li><b>事务子流程（通过消息开始事件发起）：</b>{@link org.flowable.engine.impl.bpmn.behavior.EventSubProcessMessageStartEventActivityBehavior}</li>
     *      <li><b>事务子流程（通过条件开始事件发起）：</b>{@link org.flowable.engine.impl.bpmn.behavior.EventSubProcessConditionalStartEventActivityBehavior}</li>
     *      <li><b>事务子流程（通过升级开始事件发起）：</b>{@link org.flowable.engine.impl.bpmn.behavior.EventSubProcessEscalationStartEventActivityBehavior}</li>
     *      <li><b>事务子流程（通过注册开始事件发起）：</b>{@link org.flowable.engine.impl.bpmn.behavior.EventSubProcessEventRegistryStartEventActivityBehavior}</li>
     *      <li><b>事务子流程（通过信号开始事件发起）：</b>{@link org.flowable.engine.impl.bpmn.behavior.EventSubProcessSignalStartEventActivityBehavior}</li>
     *      <li><b>事务子流程（通过定时器开始事件发起）：</b>{@link org.flowable.engine.impl.bpmn.behavior.EventSubProcessTimerStartEventActivityBehavior}</li>
     *      <li><b>事务子流程（通过变量监听开始事件发起）：</b>{@link org.flowable.engine.impl.bpmn.behavior.EventSubProcessVariableListenerlStartEventActivityBehavior}</li>
     *      <li><b>消息中间捕获事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.IntermediateCatchMessageEventActivityBehavior}</li>
     *      <li><b>信号中间捕获事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.IntermediateCatchSignalEventActivityBehavior}</li>
     *      <li><b>定时器中间捕获事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.IntermediateCatchTimerEventActivityBehavior}</li>
     *      <li><b>条件中间捕获事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.IntermediateCatchConditionalEventActivityBehavior}</li>
     *      <li><b>事件注册中间捕获事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.IntermediateCatchEventRegistryEventActivityBehavior}</li>
     *      <li><b>变量监听器中间捕获事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.IntermediateCatchVariableListenerEventActivityBehavior}</li>
     *      <li><b>补偿中间抛出事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.IntermediateThrowCompensationEventActivityBehavior}</li>
     *      <li><b>升级中间抛出事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.IntermediateThrowEscalationEventActivityBehavior}</li>
     *      <li><b>空中间抛出事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.IntermediateThrowNoneEventActivityBehavior}</li>
     *      <li><b>信号中间抛出事件：</b>{@link org.flowable.engine.impl.bpmn.behavior.IntermediateThrowSignalEventActivityBehavior}</li>
     *      <li><b>并行多实例：</b>{@link org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior}</li>
     *      <li><b>串行多实例：</b>{@link org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior}</li>
     *  </ol>
     **/
    @Test
    public void test() {

    }

    /**
     *  <h2>关于 Behavior 的使用</h2>
     *  <p>
     *      只需要自定义创建的类继承上述列表的某个类进行扩展实现,同时将自定义的扩展实现添加到自定义流程活动工厂类中。此时需要将自定工厂类注册到工作流引擎中：
     *   <ol>
     *       <li>
     *           <b>自定义Behavior扩展：</b>{@link CustomUserTaskActivityBehavior}
     *       </li>
     *       <li>
     *           <b>Behavior扩展添加至工厂：</b>{@link CustomActivityBehaviorFactory}
     *       </li>
     *       <li>
     *           <b>将自定义流程活动工厂注册至工作流引擎：</b>{@link FlowableEngineConfiguration}
     *       </li>
     *   </ol>
     *  </p>
     *  <h2>流程案例演示</h2>
     *  <p>
     *      该流程是运维申请流程，其中“专家服务”用户任务只配置了1个候选人。</br>
     *      <ul>
     *          <li><b>流程定义文件：</b>{@link flow/customActivityBehaviorProcess.bpmn20.xml}</li>
     *          <li>
     *              <b>流程预览图：</b></br>
     *              <img src="https://cdn4.winhlb.com/2025/06/06/68429d838e595.png" >
     *          </li>
     *      </ul>
     *  </p>
     **/
    @Test
    public void test1() {
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("flow/customActivityBehaviorProcess.bpmn20.xml")
                .name("自定义流程活动行为案例")
                .deploy();
        //流程定义信息
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deploy.getId())
                .singleResult();
        log.info("流程定义ID：{}", processDefinition.getId());

        //启动流程实例
        ProcessInstance procInst = runtimeService.startProcessInstanceById(processDefinition.getId());
        TaskQuery taskQuery = taskService.createTaskQuery()
                .processInstanceId(procInst.getId());
        //查询第一个用户任务
        Task firstTask = taskQuery.singleResult();
        log.info("第一个用户任务：{}", JSON.toJSONString(firstTask, taskFilter));
        //办理完成第一个用户任务
        taskService.complete(firstTask.getId());
        //查询第二个用户任务
        Task secondTask = taskQuery.singleResult();
        log.info("第二个用户任务：{}", JSON.toJSONString(secondTask, taskFilter));
        List<IdentityLink> identityLinks = taskService
                .getIdentityLinksForTask(secondTask.getId());
        log.info("办理/候选人：{}", JSON.toJSONString(identityLinks, identityLinkFilter));
        //办理完成第二个用户任务
        taskService.complete(secondTask.getId());

        /**
         *  演示结果：
         *  2025-06-06 15:57:00.529  INFO 35928 --- [           main] c.b.n.f.b.c.a.CusFlowActivityTest        : 流程定义ID：customActivityBehaviorProcess:2:25004
         * 2025-06-06 15:57:00.930  INFO 35928 --- [           main] c.b.n.f.b.c.a.CusFlowActivityTest        : 第一个用户任务：{"assignee":"安琪拉","name":"运维申请"}
         * 2025-06-06 15:57:00.943  INFO 35928 --- [           main] f.b.c.f.b.CustomUserTaskActivityBehavior : TaskId为25013的用户任务只有一个候选人，将设置为办理人
         * 2025-06-06 15:57:00.969  INFO 35928 --- [           main] c.b.n.f.b.c.a.CusFlowActivityTest        : 第二个用户任务：{"assignee":"亚瑟","name":"专家服务"}
         * 2025-06-06 15:57:00.978  INFO 35928 --- [           main] c.b.n.f.b.c.a.CusFlowActivityTest        : 办理/候选人：[{"taskId":"25013","type":"assignee","userId":"亚瑟"}]
         **/
    }

    SimplePropertyPreFilter taskFilter = new SimplePropertyPreFilter(Task.class,
            "taskId", "name", "assignee");
    SimplePropertyPreFilter identityLinkFilter =
            new SimplePropertyPreFilter(IdentityLink.class, "taskId", "type", "userId");
}
